package com.amumu.drama.common.base.mapstruct;

import org.mapstruct.*;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * MapStruct映射基类，直接继承接口即可使用通用方法，针对性指定需在继承类的接口方法上指定
 *
 * 例: public interface xxxMapping extends BaseMapping<xxxDO, xxxDTO>
 *
 * 具体用法可参考单元测试，建议配合MapStruct Support插件使用
 */
@MapperConfig(componentModel = "spring")
public interface BaseMapping<S, T> {

    /** 正向映射 */
    @InheritConfiguration
    T convertTo(S obj);

    /** 反向映射 */
    @InheritInverseConfiguration(name = "convertTo")
    S convertFrom(T obj);

    /** 正向映射（List) */
    default List<T> convertTo(List<S> list) {
        if (list == null) {
            return null;
        }

        List<T> result = new ArrayList<T>(list.size());
        for (S s : list) {
            if (s == null) {
                continue;
            }
            result.add(convertTo(s));
        }

        return result;
    }

    /** 反向映射（List) */
    default List<S> convertFrom(List<T> list) {
        if (list == null) {
            return null;
        }

        List<S> result = new ArrayList<S>(list.size());
        for (T t : list) {
            if (t == null) {
                continue;
            }
            result.add(convertFrom(t));
        }

        return result;
    }

    /** 正向映射的后置处理，List映射会自动继承此配置 */
    @AfterMapping
    default void handleAfterConvertTo(S src, @MappingTarget T dest) {
        afterConvertTo(src, dest);
    }

    /** 反向映射的后置处理，List映射会自动继承此配置 */
    @AfterMapping
    default void handleAfterConvertFrom(T src, @MappingTarget S dest) {
        afterConvertFrom(src, dest);
    }

    /** 正向映射的后置处理，List映射会自动继承此配置 */
    default void afterConvertTo(S src, T dest) {
        //TODO 覆盖此方法处理其他复杂转换逻辑
    }

    /** 反向映射的后置处理，List映射会自动继承此配置 */
    default void afterConvertFrom(T src, S dest) {
        //TODO 覆盖此方法处理其他复杂转换逻辑
    }

//    /** 正向映射（stream) */
//    @InheritConfiguration(name = "convertTo")
//    Stream<T> convertTo(Stream<S> stream);
//
//    /** 反向映射（stream) */
//    @InheritConfiguration(name = "convertFrom")
//    Stream<S> convertFrom(Stream<T> stream);
}

